#include "at_device.h"

stcATDev ATdev;

static emATResult AT_SendCmd(stcATConfig *at_config);
static void AT_ReceiveProcess(emATCommand cmd);


//AT 客户端框架初始化
void ATClient_Init(void)
{
	BSP_Timer3_init(250); /*用于空闲中断*/
	BSP_UARTx_Init(M0P_UART0,9600, UartMskNone);
	BinSem_UART_Idle = xSemaphoreCreateBinary(); /*创建二值信号量*/
}


/*****************************************************************
* 功能：发送AT指令
* 输入: p_at_config：AT配置结构体
* 输出：void
* 返回值： 
******************************************************************/
emATResult AT_SendCmd(stcATConfig *at_config)
{
	emATResult ret = Okay;
	BaseType_t xResult;
	
	memset(AT_RXbuff.Recv, 0, RXBUFF_MAXSize);  /*接收buf清零,buff只有一个任务操作,安全*/  
	AT_RXbuff.rx_len = 0;
	
	for(int i = 0; i < at_config->max_try_times; i++)
	{
		//printf("%s",at_config->p_send); 	
		BSP_UARTx_Putstr(M0P_UART0,at_config->p_send);
		
		//等待uart中断接收完数据,最大等待时间为:wait_ack_dalay1ms
		if(xSemaphoreTake(BinSem_UART_Idle,pdMS_TO_TICKS(at_config->wait_ack_dalay1ms)))
		{
			/*查找接收buff中是否有"OK\r\n字符串"*/
			if(strstr((char*)AT_RXbuff.Recv,"OK\r\n"))
			{
				return Okay;  // 收到ack数据		
			}		
		}
		else
		{
			//printf("wait ATserver ack ,Time out!!");
			ret = Error_NoResponse;
		}		
	}
	// 每次都失败才会执行到这里
	// add reset ATServer here	
	return ret;
}


/*AT ack 接收回调函数*/
void ATClient_RecvProcess(emATCommand cmd)
{
	char *pt;
	switch (cmd)
	{
		case CMD_IMEI:
		//+CGSN: 869951040379202
		//
		//OK		
		pt = strstr((char*)AT_RXbuff.Recv,"+CGSN:");
		if(pt)
		{
			pt+=6;
			memcpy(ATdev.imei,pt,17);		
			printf("imei = %s\r\n",ATdev.imei);
		}
		break;
		case CMD_ICCID:
		//+QCCID: 89861120248012012943
		//
		//OK
		pt = strstr((char*)AT_RXbuff.Recv,"+QCCID:");
		if(pt)
		{
			pt+=7;
			memcpy(ATdev.iccid,pt,22);		
			printf("iccid = %s\r\n",ATdev.iccid);
		}
		break;
		//printf("iccid = %s\r\n",ATdev.iccid);

		
		case CMD_CSQ:
		
		break;    
	default:
		break;
	}
}


emATResult ATClient_SendAT(void)
{
	stcATConfig CMDcfg;	
	CMDcfg.CommandName = CMD_AT;
	CMDcfg.p_send = "AT\r\n";
	CMDcfg.max_try_times = 3;
	CMDcfg.wait_ack_dalay1ms = 5000; /*5s*/
	CMDcfg.max_reset_times = 1;
	emATResult ret = AT_SendCmd(&CMDcfg);
	if(ret == Okay)
	{
		printf("AT dev echo OK !\r\n"); // test
		return Okay; 
	}	
	return ret;
}


// 关闭回显命令
emATResult ATClient_SetEchoOff(void)
{
	stcATConfig CMDcfg;	
	CMDcfg.CommandName = CMD_ATE0;
	CMDcfg.p_send = "ATE0\r\n";
	CMDcfg.max_try_times = 3;
	CMDcfg.wait_ack_dalay1ms = 5000; /*5s*/
	CMDcfg.max_reset_times = 1;
	emATResult ret = AT_SendCmd(&CMDcfg);
	if(ret == Okay)
	{
		printf("AT dev echo off OK !\r\n"); // test
		return Okay; 
	}	
	return ret;
}



emATResult ATClient_Get_IMEI(void)
{
	stcATConfig CMDcfg;	
	CMDcfg.CommandName = CMD_IMEI;
	CMDcfg.p_send = "AT+CGSN=1\r\n";
	CMDcfg.max_try_times = 3;
	CMDcfg.wait_ack_dalay1ms = 5000; /*5s*/
	CMDcfg.max_reset_times = 1;
	emATResult ret = AT_SendCmd(&CMDcfg);
	if(ret == Okay)
	{				
		ATClient_RecvProcess(CMDcfg.CommandName); 	
		return Okay; 
	}	
	return ret;
}

//获取nb的ICCID
//+QCCID: 89861120248012012943
//
//OK
emATResult ATClient_Get_ICCID(void)
{
	stcATConfig IccidCfg;	
	IccidCfg.CommandName = CMD_ICCID;
	IccidCfg.p_send = "AT+QCCID\r\n";
	IccidCfg.max_try_times = 3;
	IccidCfg.wait_ack_dalay1ms = 5000; /*5s*/
	IccidCfg.max_reset_times = 1;
	emATResult ret = AT_SendCmd(&IccidCfg);
	if(ret == Okay)
	{				
		ATClient_RecvProcess(IccidCfg.CommandName);
		
		return Okay; 
	}	
	return ret;
}



/*获取信号强度与信道误码率ber
+CSQ: 15,0

OK

+CSCON: 1

+CSCON: 0

**********************************************************/
emATResult ATClient_Get_Signal_Rssi(void)
{
	stcATConfig RssiCfg;	
	RssiCfg.CommandName = CMD_CSQ;
	RssiCfg.p_send = "AT+CSQ\r\n";
	RssiCfg.max_try_times = 3;
	RssiCfg.wait_ack_dalay1ms = 5000; /*5s*/
	RssiCfg.max_reset_times = 1;
	emATResult ret = AT_SendCmd(&RssiCfg);
	if(ret == Okay)
	{				
		ATClient_RecvProcess(RssiCfg.CommandName); 		
		return Okay; 
	}	
	return ret;
}


/*禁用psm模式
直接返回OK
*/
emATResult ATClient_Set_DisablePSMMode(void)
{
	stcATConfig CMDCfg;	
	CMDCfg.CommandName = CMD_DISABLE_PSM_MODE;
	CMDCfg.p_send = "AT+QSCLK=0\r\n";
	CMDCfg.max_try_times = 3;
	CMDCfg.wait_ack_dalay1ms = 5000; /*5s*/
	CMDCfg.max_reset_times = 1;
	emATResult ret = AT_SendCmd(&CMDCfg);
	if(ret == Okay)
	{				
		printf("AT dev Disable PSM mode OK !\r\n"); // test
		return Okay; 
	}	
	return ret;
}



/*获取URC数据*/
emATResult ATClient_Get_URC_buff(void)
{
	stcATConfig URCCfg;	
	URCCfg.CommandName = CMD_URC;
	URCCfg.p_send = "AT+NMGR\r\n";
	URCCfg.max_try_times = 3;
	URCCfg.wait_ack_dalay1ms = 5000; /*5s*/
	URCCfg.max_reset_times = 1;
	emATResult ret = AT_SendCmd(&URCCfg);
	if(ret == Okay)
	{				
		ATClient_RecvProcess(URCCfg.CommandName); 		
		return Okay; 
	}	
	return ret;
}


/*获取ADC电压
+QADC: 0,819

OK
*/
emATResult ATClient_Get_ADC(void)
{
	stcATConfig CMDCfg;	
	CMDCfg.CommandName = CMD_ADC;
	CMDCfg.p_send = "AT+QADC\r\n";
	CMDCfg.max_try_times = 3;
	CMDCfg.wait_ack_dalay1ms = 5000; /*5s*/
	CMDCfg.max_reset_times = 1;
	emATResult ret = AT_SendCmd(&CMDCfg);
	if(ret == Okay)
	{				
		ATClient_RecvProcess(CMDCfg.CommandName); 		
		return Okay; 
	}	
	return ret;
}


/*获取 GMT时间*/
emATResult ATClient_Get_GMTtime(void)
{
	stcATConfig CMDCfg;	
	CMDCfg.CommandName = CMD_GMTTIME;
	CMDCfg.p_send = "AT+NMGR\r\n";
	CMDCfg.max_try_times = 3;
	CMDCfg.wait_ack_dalay1ms = 5000; /*5s*/
	CMDCfg.max_reset_times = 1;
	emATResult ret = AT_SendCmd(&CMDCfg);
	if(ret == Okay)
	{				
		ATClient_RecvProcess(CMDCfg.CommandName); 		
		return Okay; 
	}	
	return ret;
}


/*发送用户透传数据
用户数据拼接,这里需修改
*/
emATResult ATClient_Send_Usrdata(void)
{
	stcATConfig URCCfg;	
	URCCfg.CommandName = CMD_SENDDAT;
	URCCfg.p_send = "AT+NMGR\r\n";
	URCCfg.max_try_times = 3;
	URCCfg.wait_ack_dalay1ms = 5000; /*5s*/
	URCCfg.max_reset_times = 1;
	emATResult ret = AT_SendCmd(&URCCfg);
	if(ret == Okay)
	{				
		ATClient_RecvProcess(URCCfg.CommandName); 		
		return Okay; 
	}	
	return ret;
}



